package com.portal.listener;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.portal.constant.MQConst;
import com.portal.constant.RedisConst;
import com.portal.enums.OrderStatus;
import com.portal.mapper.ItemMapper;
import com.portal.mapper.OrderMapper;
import com.portal.model.entity.Item;
import com.portal.model.entity.Order;
import com.portal.model.vo.CartVo;
import com.portal.service.CartService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

/**
 * 超时未支付私信队列的监听器： 监听到的就是超时的消息！ 生成订单过了40分钟
 */
@Component
@Slf4j
public class OrderStatusListener {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private RedisTemplate redisTemplate;


    // 监听私信队列的消息，也就是生成订单40分钟后： 超时未支付？
    @RabbitListener(queues = MQConst.ORDER_DLX_QUEUE)
    public void clearCart(Order order, Channel channel, Message message) throws IOException {
        log.info("超时未支付私信队列的监听器,订单信息：{}",order);

        //1、查询数据库中订单，判断订单状态，是否已经支付
        Order orderDB = orderMapper.selectById(order.getId());
        if (orderDB.getState().equals(OrderStatus.NO_PAY.getCode())) {
            //2、如果已经支付，则不需要处理； 如果未支付： 取消订单、回退预扣减的库存

            // 2.1 取消订单
            orderDB.setState(OrderStatus.ALREADY_CANCEL.getCode());
            orderMapper.updateById(orderDB);

            // 2.1 回退预扣减的Redis中的库存
            // 查询订单项
            List<Item> itemList = itemMapper.selectList(
                    Wrappers.<Item>lambdaQuery().eq(Item::getOrderId, order.getId())
            );
            for (Item item : itemList) {
                // 回退Redis中的库存
                Long bookId = item.getBookId();
                redisTemplate.opsForHash().increment(RedisConst.BOOK_STORAGE, bookId.toString(), item.getBuyCount());

                // 更改订单明细表中状态
                item.setState(OrderStatus.ALREADY_CANCEL.getCode());
                itemMapper.updateById(item);
            }
        }

        // 消息手动确认
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
}














